package ro.ubbcluj.android.PhysiTrack;

import helper.FileIOHelper;
import image.Analyzer;
import image.OwnImage;
import java.io.IOException;

import process.ImageErrorException;
import process.ProcIm;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

public class PhysiTrackActivity extends Activity {

	private Context context = this;
	private static final String TAG = PhysiTrackActivity.class.getSimpleName();
	private SurfaceView preview = null;
	private SurfaceHolder previewHolder = null;
	private Camera camera = null;
	private boolean inPreview = false;
	private boolean paramsSet;
	private boolean isRunning;
	private EditText text1, text2;
	private TextView velText, accText;
	private double sigmaM, sigmaW;
	private long timestamp;
	private Analyzer analyzer;
	private int camWidth, camHeight;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.main);
		FileIOHelper.newFolder("/PhysiTrack");
		paramsSet = false;
		isRunning = false;
		preview = (SurfaceView) findViewById(R.id.cameraView);
		previewHolder = preview.getHolder();
		previewHolder.addCallback(surfaceCallback);
		previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

		text2 = (EditText) findViewById(R.id.accelerationField);
		text1 = (EditText) findViewById(R.id.velocityField);
		text1.setHint("enter sigmaM");
		text2.setHint("enter sigmaW");
		velText = (TextView) findViewById(R.id.velocityText);
		accText = (TextView) findViewById(R.id.accelerationText);
		Button startCalc = (Button) findViewById(R.id.startButton);
		analyzer = new Analyzer(0, 0);
		startCalc.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (!isRunning) {
					try {
						if (!paramsSet) {
							String text = text1.getText().toString();
							sigmaM = Double.parseDouble(text);
							text = text2.getText().toString();
							sigmaW = Double.parseDouble(text);
							paramsSet = true;
							LinearLayout rlayout1 = (LinearLayout) findViewById(R.id.info);
							rlayout1.setVisibility(View.VISIBLE);
							velText.setText("velocity");
							accText.setText("acceleration");
							velText.setVisibility(View.VISIBLE);
							accText.setVisibility(View.VISIBLE);
							
							analyzer = new Analyzer(sigmaM, sigmaW);
							
						}
						timestamp = System.currentTimeMillis();
						Button about = (Button) findViewById(R.id.aboutButton);
						about.setClickable(false);
						Button diag = (Button) findViewById(R.id.diagramButton);
						diag.setClickable(false);
						Button startCalc = (Button) findViewById(R.id.startButton);
						startCalc.setText("Stop");
						analyzer.start();
						ProcIm.init();
						camera.setPreviewCallback(new PreviewCallback() {

							public void onPreviewFrame(byte[] data,
									Camera camera) {

								Camera.Parameters parameters = camera
										.getParameters();

								camWidth = parameters.getPreviewSize().width;
								camHeight = parameters.getPreviewSize().height;
								long t = System.currentTimeMillis() - timestamp;
								OwnImage image = new OwnImage(ProcIm
										.makeBitmap(data, camWidth, camHeight),
										t);

								try {
									analyzer.updateFromFrame(image);
									String V = Double.toString(analyzer
											.getVelocity());
									String A = Double.toString(analyzer
											.getAcceleration());
									text1.setText(V);
									text2.setText(A);

								} catch (ImageErrorException e) {
									AlertDialog alertDialog = new AlertDialog.Builder(
											PhysiTrackActivity.this).create();
									alertDialog.setMessage(e.getMessage());
									alertDialog.show();
									camera.setPreviewCallback(null);
									findViewById(R.id.startButton)
											.performClick();
								}

							}

						});

					} catch (NumberFormatException e) {
						AlertDialog alertDialog = new AlertDialog.Builder(
								PhysiTrackActivity.this).create();
						alertDialog.setMessage("Type the parameters!");
						alertDialog.show();
					}
					isRunning = true;
				} else {
					camera.setPreviewCallback(null);
					Button diag = (Button) findViewById(R.id.diagramButton);
					diag.setClickable(true);
					Button about = (Button) findViewById(R.id.aboutButton);
					about.setClickable(true);
					Button startCalc = (Button) findViewById(R.id.startButton);
					startCalc.setText("Start");
					isRunning = false;
				}

			}

		});
		Button about = (Button) findViewById(R.id.aboutButton);
		about.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(
						PhysiTrackActivity.this,
						AboutActivity.class);
				startActivity(intent);
			}
		});

		Button diagram = (Button) findViewById(R.id.diagramButton);
		diagram.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				AlertDialog.Builder builder = new AlertDialog.Builder(
						PhysiTrackActivity.this);
				builder.setMessage(
						"In order to view diagrams you have to save the current data\nSave data?")
						.setCancelable(true)
						.setPositiveButton("Yes",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int id) {
										dialog.cancel();
										final Dialog savedialog = new Dialog(
												context);
										savedialog
												.setContentView(R.layout.savefile);
										savedialog.setTitle("Result");

										final EditText filename = (EditText) savedialog
												.findViewById(R.id.filename);

										Button save = (Button) savedialog
												.findViewById(R.id.saveButton);
										save.setOnClickListener(new OnClickListener() {
											public void onClick(View v) {
												String name = filename
														.getText().toString();
												try {
													FileIOHelper
															.writeToFile(name,
																	analyzer,
																	camWidth,
																	camHeight);
													Intent intent = new Intent(
															PhysiTrackActivity.this,
															DiagramActivity.class);
													intent.putExtra(
															"filepath",
															FileIOHelper
																	.getFullPath(name));
													intent.putExtra(
															"cameraWidth",
															camWidth);
													intent.putExtra(
															"cameraHeight",
															camHeight);
													savedialog.dismiss();
													startActivity(intent);
												} catch (IOException e) {
													AlertDialog alertDialog = new AlertDialog.Builder(
															PhysiTrackActivity.this)
															.create();
													alertDialog.setMessage("Error:"
															+ e.getMessage());
													alertDialog.show();
												}

											}
										});

										Button cancel = (Button) savedialog
												.findViewById(R.id.cancelButton);
										cancel.setOnClickListener(new OnClickListener() {
											public void onClick(View v) {
												savedialog.dismiss();
												Intent intent = new Intent(
														PhysiTrackActivity.this,
														FileChooser.class);
												startActivity(intent);

											}
										});

										savedialog.show();
									}
								})
						.setNegativeButton("No",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int id) {
										dialog.cancel();
										Intent intent = new Intent(
												PhysiTrackActivity.this,
												FileChooser.class);
										startActivity(intent);

									}
								});
				if (!analyzer.isSaved()) {
					AlertDialog alert = builder.create();
					alert.show();
				} else
					startActivity(new Intent(PhysiTrackActivity.this,
							FileChooser.class));

			}
		});

	}

	@Override
	public void onStart() {
		Log.d(TAG, "start application");

		super.onStart();
	}

	@Override
	public void onStop() {
		Log.d(TAG, "stop application");

		super.onStop();
	}

	private Camera.Size getBestPreviewSize(int width, int height,
			Camera.Parameters parameters) {
		Camera.Size result = null;
		for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
			if (size.width <= width && size.height <= height) {
				if (result == null) {
					result = size;
				} else {
					int resultArea = result.width * result.height;
					int newArea = size.width * size.height;
					if (newArea > resultArea) {
						result = size;
					}
				}
				Log.d(TAG, "" + size.width + "  " + size.height);
			}
		}
		return (result);
	}

	SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
		public void surfaceCreated(SurfaceHolder holder) {
			try {
				camera = Camera.open();
				camera.setPreviewDisplay(previewHolder);

			} catch (Throwable t) {
				Log.d(TAG, "Exception in setPreviewDisplay()", t);
			}
		}

		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {

			Camera.Parameters parameters = camera.getParameters();
			Camera.Size size = getBestPreviewSize(width, height, parameters);
			if (size != null) {
				parameters.setPreviewSize(size.width, size.height);
				camera.setDisplayOrientation(90);
				camera.setParameters(parameters);
				camera.startPreview();
				inPreview = true;
			}

		}

		public void surfaceDestroyed(SurfaceHolder holder) {
			if (inPreview) {
				camera.setPreviewCallback(null);
				camera.stopPreview();
			}
			camera.release();
			camera = null;
			inPreview = false;
		}

	};
}